package com.acme.mock;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.acme.bankapp.domain.bank.Bank;
import com.acme.mock.Action.Command;

public class BankServer {
	ServerSocket providerSocket;
	Socket connection = null;
	ObjectOutputStream out;
	ObjectInputStream in;
	String message;
	Bank bank;

	BankServer(Bank bank) {
		this.bank = bank;
	}

	void run() {
		try {
			providerSocket = new ServerSocket(2004, 10);
			System.out.println("Waiting for connection");
			connection = providerSocket.accept();
			System.out.println("Connection received from " + connection.getInetAddress().getHostName());
			out = new ObjectOutputStream(connection.getOutputStream());
			out.flush();
			in = new ObjectInputStream(connection.getInputStream());
			Action action = new Action(bank);
			do {
				try {
					message = (String) in.readObject();
					System.out.println("client>" + message);
					Object objectForSent =  null;
					for (Command command : Command.values()) {
						Matcher matcher = Pattern.compile(command.pattern).matcher(message);
						if(matcher.matches()){
							objectForSent = action.ActionHandler(command.command, matcher.group(1));
						}
					}
					out.writeObject(objectForSent);
				} catch (ClassNotFoundException classnot) {
					System.err.println("Data received in unknown format");
				}
			} while (!"bye".equals(message));
		} catch (IOException ioException) {
			ioException.printStackTrace();
		} finally {
			try {
				out.close();
				in.close();
				providerSocket.close();
			} catch (IOException ioException) {
				ioException.printStackTrace();
			}
		}
	}

	

	void sendMessage(final String msg) {
		try {
			out.writeObject(msg);
			out.flush();
			System.out.println("server>" + msg);
		} catch (IOException ioException) {
			ioException.printStackTrace();
		}
	}

	public static void startServer(final Bank bank) {
		BankServer server = new BankServer(bank);
		server.run();
	}

	
}
